/**
 * ui.c
 * Description: User interface implementation
 * Authors: Hamish Cumming, Brian Thorne 2008
 */

#include "ui.h"
#include "joystick.h"
#include "ButterflyLCDFunctions.h"
#include <stdio.h>
#include <string.h>
#include "mode.h"
#include "kernel.h"
/* Constants */
#define MAX_STR_LEN 30

typedef enum {NAV_MODE_SELECTION=0,NAV_NORMAL=1} ui_nav_t;

/* File vars */
static ui_nav_t ui_nav_mode;
static mode_t op_mode; //the current operating mode
static const char * str_mode_names[] = {"replay","measure","idle"};
static char strbuffer[MAX_STR_LEN]; //screen display buffer, for use by the display task

/** Displays a time_t value on the LCD */
void display_time(time_t time)
{
    char s[11]; //32bit ints cannot be any longer than this
    sprintf(s,"%lu",time.time32);
    ui_message(s);
}

/** Initialise all the user interface modules */
void ui_init()
{
    joystick_init();
    LCD_initDisplay();
    LCD_changeContrast(15);
    ui_nav_mode = NAV_MODE_SELECTION;
    op_mode = IDLE;
    register_task(display_task, DISPLAY_TASK);
}

/** Writes a string to the display buffer */
void ui_message(const char *string)
{
    if((strlen(string) + 1) * sizeof(char) > MAX_STR_LEN) return;
    //copy the string to the display buffer
    strcpy(strbuffer, string);
    //actiave the display task
    task_flags[DISPLAY_TASK] = ACTIVATED;
}

/** Updates the display */
uint8_t display_task(void)
{

    LCD_showString(strbuffer);
    return EXIT_SLEEP;
}

/** The response to the joystick */
void ui_move(direction_t direction)
{
    if(!(direction>>1)) // Check if direction is left or right (0 or 1)
    {// Immediatly move string left or right.
        ui_string_move(direction);
        return;
    }
    /* If in mode select - up and down change mode on screen. Enter confirms */
    if(ui_nav_mode==NAV_MODE_SELECTION)
    {
        /* enter has to be pushed to select */
        if(direction == push)
        {
            set_mode(op_mode);
            ui_nav_mode = NAV_NORMAL;
            return;
        }
        /* Take care of the wrapping around */
        if (direction == up)
        {
            if (++op_mode > IDLE) op_mode = REPLAY;
        }
        else if (direction == down)
        {
            if (op_mode == REPLAY) op_mode = IDLE;
            else op_mode--;
        }
        ui_message(str_mode_names[op_mode]); //show the mode and description
    }
    else if(ui_nav_mode==NAV_NORMAL)
    {
        if(direction == push)   // Enters mode selection.
        {
            ui_nav_mode = NAV_MODE_SELECTION;
            op_mode = get_mode();
            ui_message(str_mode_names[op_mode]);
            return;

        } else { //Direction must be up or down.
            mode_action(direction);
        }
    }
}

/** Moves a string left or right */
void ui_string_move(direction_t direction)
{
    LCD_scrollDisplay(!direction, TEXT_WRAP);
}
